home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Format / p2explode / p2explode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  18.3 KB  |  869 lines

  1. /* p2explode: explode a P2 structure up into component parts in hierachy */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Format/p2explode/RCS/p2explode.c,v 6.0 1991/12/18 20:20:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Format/p2explode/RCS/p2explode.c,v 6.0 1991/12/18 20:20:02 jpo Rel $
  9.  *
  10.  * $Log: p2explode.c,v $
  11.  * Revision 6.0  1991/12/18  20:20:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "retcode.h"
  20. #include <isode/psap.h>
  21. #include <isode/cmd_srch.h>
  22. #include "tb_bpt88.h"
  23. #include "IOB-types.h"
  24. #include <varargs.h>
  25. #include "q.h"
  26. #include "list_bpt.h"
  27. static int process();
  28. static FILE *open_IOB_file();
  29. static char curdir[MAXPATHLENGTH];   /* directory stack */
  30. int    err_fatal = NOTOK;
  31.  
  32. extern CMD_TABLE bptbl_body_parts88[/* x400 84 body_parts */];
  33. extern char *quedfldir;
  34. extern char *hdr_p22_bp, *hdr_p2_bp, *hdr_ipn_bp, *cont_p22, *cont_p2;
  35. LIST_BPT    *outbound_bpts = NULLIST_BPT;
  36. LIST_BPT    *outbound_hdrs = NULLIST_BPT;
  37.  
  38. void    advise ();
  39. void    adios ();
  40. #define ps_advise(ps, f) \
  41.     advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s",\
  42.         (f), ps_error ((ps) -> ps_errno))
  43. char    *makename();
  44.  
  45. unflatten(old, new, x40084, qp, perr)
  46. char    *old,
  47.     *new;
  48. int    x40084;
  49. Q_struct    *qp;
  50. char        **perr;
  51. {
  52.     char    curpart[LINESIZE], buf[BUFSIZ];
  53.     
  54.     setname (new);       /* set initial directory */
  55.     msg_rinit(old);
  56.     err_fatal = NOTOK;
  57.     if (!(msg_rfile(curpart) == RP_OK && isP2(curpart, x40084))) {
  58.         PP_LOG(LLOG_EXCEPTIONS,
  59.                ("Chans/p2explode cannot find %s file in '%s'",
  60.             (x40084 == TRUE) ? cont_p2 : cont_p22,
  61.             old));
  62.         (void) sprintf (buf,
  63.                 "Unable to find %s file in '%s'",
  64.                 (x40084 == TRUE) ? cont_p2 : cont_p22,
  65.                 old);
  66.         *perr = strdup(buf);
  67.         return NOTOK;
  68.     }
  69.     if (process (curpart, x40084, qp, perr) == NOTOK)
  70.         return NOTOK;
  71.     return OK;
  72. }
  73.  
  74. /*
  75.  * isP2: check to see if the current body part should be
  76.  * processed or not.
  77.  */
  78.  
  79. isP2(curpart, x40084)
  80. char    *curpart;
  81. int    x40084;
  82. {
  83.     char    *cp;
  84.  
  85.     if ((cp = rindex(curpart,'/')) != NULLCP)
  86.         cp ++;
  87.     else cp = curpart;
  88.  
  89.     return (strcmp(cp, ((x40084 == TRUE) ? cont_p2 : cont_p22)) == 0);
  90. }
  91.  
  92. extern  errno;
  93.  
  94. /* linkthem: no reformatting needed so just link across */
  95.  
  96. linkthem(src, dest, perr)
  97. char    *src, *dest, **perr;
  98. {
  99.     char    buf[BUFSIZ];
  100.  
  101.     if(link(src, dest) < 0 && errno != EEXIST) {
  102.         PP_SLOG(LLOG_EXCEPTIONS, "link",
  103.             ("cannot link %s to %s", src, dest));
  104.         (void) sprintf (buf,
  105.                 "Unable to link %s to %s",
  106.                 src, dest);
  107.         *perr = strdup(buf);
  108.         return NOTOK;
  109.     }
  110.     return OK;
  111. }
  112.  
  113. /* process: start the splitting operation on the given file */
  114. static int     process (file, x40084, qp, perr)
  115. register char  *file;
  116. int        x40084;
  117. Q_struct    *qp;
  118. char        **perr;
  119. {
  120.     register PE     pe;
  121.     register PS     psin;
  122.     FILE        *fp;
  123.     char        buf[BUFSIZ];
  124.     int        retval = NOTOK;
  125.     struct type_IOB_InformationObject *infoob;
  126.  
  127.     if((fp = fopen (file, "r")) == (FILE *)0) {
  128.         PP_SLOG(LLOG_EXCEPTIONS, file,
  129.                ("Can't open file"));
  130.         (void) sprintf (buf,
  131.                 "Unable to open input file '%s'",
  132.                 file);
  133.         *perr = strdup(buf);
  134.         return NOTOK;
  135.     }
  136.  
  137.     if ((psin = ps_alloc (std_open)) == NULLPS)
  138.     {
  139.         (void) fclose (fp);
  140.         ps_advise (psin, "ps_alloc");
  141.         return NOTOK;
  142.     }
  143.  
  144.     if (std_setup (psin, fp) == NOTOK)
  145.     {
  146.         ps_free (psin);
  147.         (void) fclose (fp);
  148.         advise (LLOG_EXCEPTIONS, NULLCP, "%s: std_setup loses", file);
  149.         return NOTOK;
  150.     }
  151.  
  152.     if ((pe = ps2pe (psin)) == NULLPE) { /* EOF or error? */
  153.         (void) fclose (fp);
  154.         err_fatal = OK;
  155.         (void) sprintf(buf,
  156.             "Unable to parse the p2 - ps2pe failed");
  157.         *perr = strdup(buf);
  158.         ps_done(psin, "ps2pe");
  159.         return NOTOK;
  160.     }
  161.     PY_pepy[0] = 0;
  162.  
  163.     if(decode_IOB_InformationObject(pe, 1, NULLIP, NULLVP, &infoob) == NOTOK) {
  164.         PP_LOG(LLOG_EXCEPTIONS,
  165.                ("decode_IOB_InformationObject failure [%s]", 
  166.             PY_pepy));
  167.         pe_done(pe, "Parse failure IOB_InformationObject");
  168.         err_fatal = OK;
  169.         (void) sprintf (buf,
  170.                 "Unable to parse the p2 [%s]",
  171.                 PY_pepy);
  172.         *perr = strdup (buf);
  173.         (void) fclose(fp);
  174.         return NOTOK;
  175.     }
  176.     if (PY_pepy[0] != 0)
  177.         PP_LOG(LLOG_EXCEPTIONS,
  178.                ("parse_IOB_InformationObject non fatal failure [%s]",
  179.             PY_pepy));
  180.     if (write_out_parts (infoob, x40084, qp, perr) == OK)
  181.         retval = OK;
  182.     if( pe != NULLPE)
  183.         pe_free (pe);
  184.     (void) fclose (fp);
  185.     return retval;
  186. }
  187.  
  188. write_out_parts (infoob, x40084, qp, perr)
  189. struct type_IOB_InformationObject *infoob;
  190. int    x40084;
  191. Q_struct    *qp;
  192. char        **perr;
  193. {
  194.     char    buf[BUFSIZ];
  195.  
  196.     switch (infoob -> offset) {
  197.         case type_IOB_InformationObject_ipm:
  198.         return write_ipm (infoob -> un.ipm, x40084, qp, perr);
  199.  
  200.         case type_IOB_InformationObject_ipn:
  201.         return write_ipn (infoob -> un.ipn, x40084, qp, perr);
  202.  
  203.         default:
  204.         PP_LOG (LLOG_EXCEPTIONS,
  205.             ("Unknown P2 type %d", infoob -> offset));
  206.         (void) sprintf (buf,
  207.                 "Unknown P2 type %d",
  208.                 infoob -> offset);
  209.         *perr = strdup(buf);
  210.         return NOTOK;
  211.     }
  212. }
  213.  
  214. int    write_ipm (ipm, x40084, qp, perr)
  215. struct type_IOB_IPM *ipm;
  216. int x40084;
  217. Q_struct    *qp;
  218. char        **perr;
  219. {
  220.     if (write_heading (x40084, ipm -> heading, qp, perr) == NOTOK) 
  221.         return NOTOK;
  222.  
  223.     return write_bodies (ipm -> body, 1, x40084, qp, perr);
  224. }
  225.  
  226. int    write_bodies (bpp, number, x40084, qp, perr)
  227. struct type_IOB_Body *bpp;
  228. int    number;
  229. int    x40084;
  230. Q_struct    *qp;
  231. char        **perr;
  232. {
  233.     struct type_IOB_BodyPart *bp;
  234.     FILE    *fp;
  235.     char    buf[BUFSIZ];
  236.  
  237.     while (bpp) {
  238.         bp = bpp -> BodyPart;
  239.         bpp = bpp->next;
  240.  
  241.         switch (bp -> offset) {
  242.             case type_IOB_BodyPart_ia5__text:
  243.             if ((fp = open_IOB_file (BPT_IA5, number, 
  244.                          qp, perr)) == NULLFILE)
  245.                 return NOTOK;
  246.             dumpCRLFstring (fp, bp -> un.ia5__text -> data);
  247.             if (fclose (fp) == EOF)
  248.                 return NOTOK;
  249.             break;
  250.  
  251.             case type_IOB_BodyPart_tlx:
  252.             if (write_pefile (BPT_TLX, number, 1,
  253.                       (caddr_t)bp -> un.tlx,
  254.                       &_ZIOB_mod, _ZTLXBodyPartIOB,
  255.                       qp, perr) == NOTOK)
  256.                 return NOTOK;
  257.             break;
  258.  
  259.             case type_IOB_BodyPart_voice:
  260.             if (write_pefile (BPT_VOICE, number, 2,
  261.                       (caddr_t) bp -> un.voice,
  262.                       &_ZIOB_mod, _ZVoiceBodyPartIOB,
  263.                       qp, perr) == NOTOK)
  264.                 return NOTOK;
  265.             break;
  266.  
  267.  
  268.             case type_IOB_BodyPart_g3__facsimile:
  269.             if (write_pefile (BPT_G3FAX, number, 3,
  270.                       (caddr_t) bp -> un.g3__facsimile,
  271.                       &_ZIOB_mod, _ZG3FacsimileBodyPartIOB,
  272.                       qp, perr) == NOTOK)
  273.                 return NOTOK;
  274.             break;
  275.  
  276.             case type_IOB_BodyPart_g4__class1:
  277.             if (write_pefile (BPT_TIF0, number, 4,
  278.                       (caddr_t) bp -> un.g4__class1,
  279.                       &_ZIOB_mod, _ZG4Class1BodyPartIOB,
  280.                       qp, perr) == NOTOK)
  281.                 return NOTOK;
  282.             break;
  283.  
  284.             case type_IOB_BodyPart_teletex:
  285.             if (write_pefile (BPT_TTX, number, 5,
  286.                       (caddr_t) bp -> un.teletex,
  287.                       &_ZIOB_mod, _ZTeletexBodyPartIOB,
  288.                       qp, perr) == NOTOK)
  289.                 return NOTOK;
  290.             break;
  291.  
  292.             case type_IOB_BodyPart_videotex:
  293.             if (write_pefile (BPT_VIDEOTEX, number, 6,
  294.                       (caddr_t) bp -> un.videotex,
  295.                       &_ZIOB_mod, _ZVideotexBodyPartIOB,
  296.                       qp, perr) == NOTOK)
  297.                 return NOTOK;
  298.             break;
  299.  
  300.             case type_IOB_BodyPart_encrypted:
  301.             if (write_pefile (BPT_ENCRYPTED, number, 8,
  302.                       (caddr_t) bp -> un.encrypted,
  303.                       &_ZIOB_mod, _ZEncryptedBodyPartIOB,
  304.                       qp, perr) == NOTOK)
  305.                 return NOTOK;
  306.             break;
  307.  
  308.             case type_IOB_BodyPart_message:
  309.             pushdir (number);
  310.             if (do_fip (bp -> un.message, x40084, qp, perr) == NOTOK)
  311.                 return NOTOK;
  312.             popdir ();
  313.             break;
  314.             
  315.             case type_IOB_BodyPart_sfd:
  316.             if (write_pefile (BPT_SFD, number, 10,
  317.                       (caddr_t) bp -> un.sfd,
  318.                       &_ZIOB_mod, _ZSFDBodyPartIOB,
  319.                       qp, perr) == NOTOK)
  320.                 return NOTOK;
  321.             break;
  322.             
  323.             case type_IOB_BodyPart_mixed__mode:
  324.             if (write_pefile (BPT_TIF1, number, 11,
  325.                       (caddr_t) bp -> un.mixed__mode,
  326.                       &_ZIOB_mod, _ZMixedModeBodyPartIOB,
  327.                       qp, perr) == NOTOK)
  328.                 return NOTOK;
  329.             break;
  330.             case type_IOB_BodyPart_odif:
  331.             if (write_odif (bp -> un.odif, number, qp, perr) == NOTOK)
  332.                 return NOTOK;
  333.             break;
  334.  
  335.             case type_IOB_BodyPart_nationally__defined:
  336.             if (write_pefile (BPT_NATIONAL, number, 7,
  337.                       (caddr_t) bp -> un.nationally__defined,
  338.                       &_ZIOB_mod, _ZNationallyDefinedBodyPartIOB,
  339.                       qp, perr) == NOTOK)
  340.                 return NOTOK;
  341.             break;
  342.             
  343.             case type_IOB_BodyPart_bilaterally__defined:
  344.             if (write_pefile (BPT_BILATERAL, number, 14,
  345.                       (caddr_t) bp -> un.bilaterally__defined,
  346.                       &_ZIOB_mod, _ZBilaterallyDefinedBodyPartIOB,
  347.                       qp, perr) == NOTOK)
  348.                 return NOTOK;
  349.             break;
  350.             
  351.             case type_IOB_BodyPart_externally__defined:
  352.             if (write_pefile (BPT_EXTERNAL, number, 15,
  353.                       (caddr_t) bp -> un.externally__defined,
  354.                       &_ZIOB_mod, _ZExternallyDefinedBodyPartIOB,
  355.                       qp, perr) == NOTOK)
  356.                 return NOTOK;
  357.             break;
  358.             
  359.             case type_IOB_BodyPart_iso6937Text:
  360.             if (write_pefile (BPT_ISO6937TEXT, number, 13,
  361.                       (caddr_t) bp -> un.iso6937Text,
  362.                       &_ZIOB_mod, _ZISO6937TextBodyPartIOB,
  363.                       qp, perr) == NOTOK)
  364.                 return NOTOK;
  365.             break;
  366.             
  367.             default:
  368.             PP_LOG (LLOG_EXCEPTIONS,
  369.                 ("Unknown body part type %d",
  370.                  bp -> offset));
  371.             (void) sprintf (buf,
  372.                     "Unknown body part type %d",
  373.                     bp->offset);
  374.             *perr = strdup (buf);
  375.             return NOTOK;
  376.         }
  377.         number ++;
  378.     }
  379.     return OK;
  380. }
  381.  
  382. write_heading (x40084, heading, qp, perr)
  383. int    x40084;
  384. struct type_IOB_Heading    *heading;
  385. Q_struct    *qp;
  386. char        **perr;
  387. {
  388.     FILE    *fp;
  389.     PE    pe;
  390.     char    buf[BUFSIZ];
  391.  
  392.     if (encode_IOB_Heading(&pe, 1, NULL, NULLCP, heading) == NOTOK) {
  393.         PP_LOG (LLOG_EXCEPTIONS, ("Can't encode heading - %s",
  394.                       PY_pepy));
  395.         (void) sprintf (buf,
  396.                 "Unable to encode heading - %s",
  397.                 PY_pepy);
  398.         *perr = strdup(buf);
  399.     }
  400.  
  401.     if ((fp = open_IOB_file ((x40084 == TRUE) ? BPT_HDR_P2 : BPT_HDR_P22,
  402.                  0, qp, perr)) == NULLFILE) {
  403.         pe_free (pe);
  404.         return NOTOK;
  405.     }
  406.  
  407.     if (write_pe (pe, fp) == NOTOK) {
  408.         (void) fclose (fp);
  409.         pe_free (pe);
  410.         *perr = strdup("Unable to write_heading");
  411.         return NOTOK;
  412.     }
  413.  
  414.     pe_free (pe);
  415.     if (fclose (fp) == EOF)
  416.         return NOTOK;
  417.     return OK;
  418. }
  419.     
  420. write_pefile (type, number, tag, parm, pmod, idx, qp, perr)
  421. int    type, number, tag;
  422. caddr_t    parm;
  423. modtyp    *pmod;
  424. int    idx;
  425. Q_struct    *qp;
  426. char    **perr;
  427. {
  428.     FILE    *fp;
  429.     PE    pe;
  430.     char    buf[BUFSIZ];
  431.     if (enc_f(idx, pmod, &pe, 1, NULL, NULLCP, parm) == NOTOK) {
  432.         PP_LOG (LLOG_EXCEPTIONS, ("Can't encode - %s",
  433.                       PY_pepy));
  434.         (void) sprintf (buf,
  435.                 "Unable to encode - %s",
  436.                 PY_pepy);
  437.         *perr = strdup(buf);
  438.         return NOTOK;
  439.     }
  440.     /* IMPLICIT TAG */
  441.     pe->pe_class = PE_CLASS_CONT;
  442.     pe->pe_id = tag;
  443.  
  444.     if ((fp = open_IOB_file (type, number, qp, perr)) == NULLFILE) {
  445.         pe_free (pe);
  446.         return NOTOK;
  447.     }
  448.     if (write_pe (pe, fp) == NOTOK) {
  449.         (void) fclose (fp);
  450.         pe_free (pe);
  451.         *perr = strdup("Unable to write_pefile");
  452.         return NOTOK;
  453.     }
  454.     pe_free (pe);
  455.     if (fclose (fp) == EOF)
  456.         return NOTOK;
  457.     return OK;
  458. }
  459.  
  460. int    write_odif (op, number, Qp, perr)
  461. struct type_IOB_ODIFBodyPart *op;
  462. int    number;
  463. Q_struct    *Qp;
  464. char    **perr;
  465. {
  466.     struct qbuf *qp;
  467.     FILE    *fp;
  468.  
  469.     if ((fp = open_IOB_file (BPT_ODIF, number, Qp, perr)) == NULLFILE)
  470.         return NOTOK;
  471.  
  472.     for (qp = op -> qb_forw; qp != op; qp = qp -> qb_forw)
  473.         if (fwrite (qp -> qb_data, 1, qp -> qb_len, fp)
  474.             != qp -> qb_len) {
  475.             (void) fclose (fp);
  476.             return NOTOK;
  477.         }
  478.     if (fclose (fp) == EOF)
  479.         return NOTOK;
  480.     return OK;
  481. }
  482.  
  483. write_ipn (ipn, x40084, qp, perr)
  484. struct type_IOB_IPN *ipn;
  485. int    x40084;
  486. Q_struct    *qp;
  487. char    **perr;
  488. {
  489.     PE     pe;
  490.     if (ipn->choice->offset == choice_IOB_0_non__receipt__fields
  491.         && ipn->choice->un.non__receipt__fields->returned__ipm != NULL) {
  492.         pushdir(2);
  493.         if (write_ipm (ipn -> choice -> un.non__receipt__fields->returned__ipm, x40084, qp, perr) == NOTOK)
  494.             return NOTOK;
  495.         free_IOB_IPM(ipn -> choice -> un.non__receipt__fields->returned__ipm);
  496.         ipn -> choice -> un.non__receipt__fields -> returned__ipm = NULL;
  497.         popdir();
  498.     }
  499.     
  500.     if (encode_IOB_IPN (&pe, 1, 0, NULLCP, ipn) == NOTOK) 
  501.         return NOTOK;
  502.     
  503.     if (write_bp (hdr_ipn_bp, pe, perr) == NOTOK)
  504.         return NOTOK;
  505.     return OK;
  506. }
  507.  
  508. int    do_fip (forwarded, x40084, qp, perr)
  509. struct type_IOB_MessageBodyPart *forwarded;
  510. int    x40084;
  511. Q_struct    *qp;
  512. char    **perr;
  513. {
  514.     PE    pe;
  515.  
  516.     if (forwarded -> parameters != NULL
  517.         && (forwarded -> parameters -> delivery__time != NULL
  518.         || forwarded -> parameters -> delivery__envelope != NULL)) {
  519.         /* have delivery info put out */
  520.         if (encode_IOB_MessageParameters(&pe, 1, 0, 
  521.                         NULLCP, 
  522.                         forwarded -> parameters) == NOTOK) {
  523.             *perr = strdup("Unable to encode IOB_MessageParameters for forwarded message");
  524.             return NOTOK;
  525.         }
  526.         if (write_bp (rcmd_srch (BPT_P2_DLIV_TXT, bptbl_body_parts88),
  527.                   pe,perr) == NOTOK)
  528.             return NOTOK;
  529.     }
  530.     return write_ipm (forwarded -> data, x40084, qp, perr);
  531. }
  532.  
  533. /* pe_done: utility routine to do the right thing for pe errors */
  534. int             pe_done (pe, msg)
  535. PE              pe;
  536. char            *msg;
  537. {
  538.     if (pe->pe_errno)
  539.     {
  540.         PP_OPER(NULLCP,
  541.             ("%s: [%s] %s",msg,PY_pepy,pe_error(pe->pe_errno)));
  542.         pe_free (pe);
  543.         return NOTOK;
  544.     }
  545.     else
  546.     {
  547.         pe_free (pe);
  548.         return OK;
  549.     }
  550. }
  551.  
  552. /* ps_done: like pe_done */
  553. int             ps_done (ps, msg)
  554. PS              ps;
  555. char           *msg;
  556. {
  557.     ps_advise (ps, msg);
  558.     ps_free (ps);
  559.     return NOTOK;
  560. }
  561.  
  562. /*   */
  563. /* convert from \r\n to \n */
  564.  
  565. dumpCRLFstring(fp, pstr)
  566. FILE *fp;
  567. struct type_UNIV_IA5String *pstr;
  568. {
  569.     char    lastc = NULL;
  570.     char    *cp;
  571.     struct qbuf *qb;
  572.     int    n;
  573.  
  574.     for (qb = pstr -> qb_forw; qb != pstr; qb = qb -> qb_forw) {
  575.         for (n = qb -> qb_len, cp = qb -> qb_data;
  576.              n > 0; n--, cp++) {
  577.             switch (*cp) {
  578.                 case '\r':
  579.                 lastc = *cp;
  580.                 break;
  581.  
  582.                 case '\n':
  583.                 putc (*cp, fp);
  584.                 lastc = NULL;
  585.                 break;
  586.  
  587.                 default:
  588.                 if (lastc) {
  589.                     putc (lastc, fp);
  590.                     lastc = NULL;
  591.                 }
  592.                 putc (*cp, fp);
  593.                 break;
  594.             }
  595.         }
  596.     }
  597.     if (lastc) putc (lastc, fp);
  598. }
  599.  
  600. /*
  601.  * write_bp: write a body part contained in pe out to the file named
  602.  * name. name is converted into the correct place in the directory
  603.  * tree.
  604.  */
  605.  
  606. write_bp(name, pe, perr)
  607. char    *name;
  608. PE      pe;
  609. char    **perr;
  610. {
  611.     FILE    *fp;
  612.     char    filename[MAXPATHLENGTH], buf[BUFSIZ];
  613.     
  614.     if (name[0] == '/' ||
  615.         strncmp (name, "./", 2) == 0 || strncmp (name, "../", 3) == 0)
  616.         sprintf(filename,"%s",name);
  617.     else 
  618.         sprintf(filename, "%s/%s",curdir,name);
  619.     PP_LOG(LLOG_TRACE,
  620.          ("Chans/p2explode writing %s...", filename));
  621.  
  622.     if((fp = fopen(filename, "w")) == NULL)
  623.     {
  624.         PP_SLOG(LLOG_EXCEPTIONS, filename,
  625.             ("Can't open file"));
  626.         (void) sprintf (buf,
  627.                 "Unable to open output file '%s'",
  628.                 filename);
  629.         *perr = strdup(buf);
  630.         return NOTOK;
  631.     }
  632.  
  633.     if (write_pe (pe, fp) == NOTOK) {
  634.         (void) sprintf (buf,
  635.                 "Failed to write output file '%s'",
  636.                 filename);
  637.         *perr = strdup(buf);
  638.         return NOTOK;
  639.     }
  640.     (void) fclose (fp);
  641.     return OK;
  642. }
  643.  
  644. write_pe (pe, fp)
  645. PE    pe;
  646. FILE    *fp;
  647. {
  648.     PS    psout;
  649.     if ((psout = ps_alloc(std_open)) == NULLPS)
  650.     {
  651.         ps_advise (psout, "ps_alloc");
  652.         (void) fclose (fp);
  653.         return NOTOK;
  654.     }
  655.     if (std_setup (psout, fp) == NOTOK)
  656.     {
  657.         advise (LLOG_EXCEPTIONS, NULLCP, "std_setup loses");
  658.         (void) fclose (fp);
  659.         return NOTOK;
  660.     }
  661.  
  662.     if(pe2ps(psout, pe) == NOTOK)
  663.     {
  664.         ps_advise(psout, "pe2ps loses");
  665.         return NOTOK;
  666.     }
  667.     ps_free (psout);
  668.     return OK;
  669. }
  670.  
  671. /* pushdir: used in forwarded ip messages. Decend a level in the
  672.  * directory hierachy.
  673.  */
  674. pushdir (n)
  675. int     n;
  676. {
  677.     char    *p;
  678.     char    name_buf[MAXPATHLENGTH];
  679.  
  680.     (void) sprintf(name_buf, "%d.ipm", n);
  681.     p = makename (name_buf);
  682.     setname (p);            /* clever bit - set new dir name */
  683.     if( mkdir(p, 0755) == NOTOK)
  684.         adios("mkdir", "Can't create directory %s", p);
  685.     PP_LOG(LLOG_TRACE, ("Created %s\n", p));
  686. }
  687.  
  688. /* makename: convert name into directory path */
  689. char    *makename (name)
  690. char    *name;
  691. {
  692.     static char name_buf[MAXPATHLENGTH];
  693.     if (name[0] == '/' || strncmp (name,"./", 2) == 0 ||
  694.         strncmp (name, "../", 3) ==0)
  695.         /* fullname already */
  696.         return strdup(name);
  697.     else 
  698.         (void) sprintf (name_buf, "%s/%s", curdir, name);
  699.     return name_buf;
  700. }
  701.  
  702. /* initialise name for above */
  703. setname (name)
  704. char    *name;
  705. {
  706.     (void) strcpy (curdir, name);
  707. /*    printf ("setname -> %s\n", curdir);*/
  708. }
  709.  
  710. /* popdir: counterpart of pushdir */
  711. popdir()
  712. {
  713.     char    *p;
  714.  
  715.     if(( p = rindex(curdir, '/')) != NULLCP)
  716.         *p = '\0';
  717.     else{
  718.             advise (LLOG_EXCEPTIONS,NULLCP, "Popdir - underflow");
  719.      }
  720. }
  721.  
  722. pepy2type (type)
  723. int    type;
  724. {
  725.     switch (type) {
  726.         case 0:
  727.             return BPT_IA5;
  728.         case 1:
  729.             return BPT_TLX;
  730.         case 2:
  731.             return BPT_VOICE;
  732.         case 3:
  733.             return BPT_G3FAX;
  734.         case 4:
  735.             return BPT_TIF0;
  736.         case 5:
  737.             return BPT_TTX;
  738.         case 6:
  739.             return BPT_VIDEOTEX;
  740.         case 7:
  741.             return BPT_NATIONAL;
  742.         case 8:
  743.             return BPT_ENCRYPTED;
  744. /*        case 9:
  745.             forwarded message should be dealt with else where */
  746.         case 10:
  747.             return BPT_SFD;
  748.         case 11:
  749.             return BPT_TIF1;
  750.         case 12:
  751.             return BPT_ODIF;
  752.         default:
  753.             PP_LOG(LLOG_EXCEPTIONS,
  754.                 ("Chans/p2explode unknown bpt type %d\n",type));
  755.             return BPT_UNDEFINED;
  756.     }
  757. }
  758.  
  759. static FILE *open_IOB_file(type, num, qp, perr)
  760. int    type,
  761.     num;
  762. Q_struct    *qp;
  763. char    **perr;
  764. {
  765.     char    *p = NULLCP,
  766.         filename[MAXPATHLENGTH], buf[BUFSIZ];
  767.     FILE    *fp;
  768.  
  769.     if ((p = rcmd_srch(type, bptbl_body_parts88)) != NULLCP
  770.         && qp != NULL 
  771.         && list_bpt_find (qp->encodedinfo.eit_types,
  772.                   p) == NULLIST_BPT) {
  773.         /* HACK for undeclared bp that are supported by outchan */
  774.         if (outbound_bpts &&
  775.               list_bpt_find (outbound_bpts, p) != NULLIST_BPT)
  776.             PP_LOG(LLOG_NOTICE,
  777.                    ("Bodypart '%s' present but undeclared. Outbound channel supports it so letting through", p));
  778.         else if (outbound_hdrs &&
  779.              list_bpt_find (outbound_hdrs, p) != NULLIST_BPT)
  780.             PP_LOG(LLOG_NOTICE,
  781.                    ("Headertype '%s' present but undeclared. Outbound channel supports it so letting through", p));
  782.         else {
  783.             sprintf (buf, 
  784.                  "body type '%s' present but undeclared in envelope",
  785.                  p);
  786.             *perr = strdup(buf);
  787.             err_fatal = OK;
  788.             return NULL;
  789.         } 
  790.     }
  791.     
  792.     if(p == NULLCP) {
  793.         advise(LLOG_EXCEPTIONS, NULLCP, "Unknown body type %d", type);
  794.         sprintf (filename, "%s/%d", curdir,num);
  795.     } if (type == BPT_HDR_P2 || type == BPT_HDR_P22) 
  796.         sprintf (filename, "%s/%s", curdir, p);
  797.     else
  798.             sprintf(filename, "%s/%d.%s", curdir,num, p);
  799.         
  800.     PP_LOG(LLOG_EXCEPTIONS,
  801.            ("Chans/p2explode writing %s",filename));
  802.  
  803.     if ((fp = fopen(filename, "w")) == NULL)
  804.     {
  805.         PP_SLOG(LLOG_EXCEPTIONS, filename,
  806.             ("Can't open file"));
  807.         (void) sprintf(buf,
  808.                    "Failed to open output file '%s'",
  809.                    filename);
  810.         *perr = strdup(buf);
  811.         return NULL;
  812.     }
  813.     return fp;
  814. }
  815. /*     ERRORS */
  816.  
  817. #ifndef lint
  818. void    adios (va_alist)
  819. va_dcl
  820. {
  821.     va_list ap;
  822.  
  823.     va_start (ap);
  824.  
  825.     _ll_log (pp_log_norm, LLOG_FATAL, ap);
  826.  
  827.     va_end (ap);
  828.  
  829.     _exit (1);
  830. }
  831. #else
  832. /* VARARGS2 */
  833.  
  834. void    adios (what, fmt)
  835. char   *what,
  836.        *fmt;
  837. {
  838.     adios (what, fmt);
  839. }
  840. #endif
  841.  
  842.  
  843. #ifndef lint
  844. void    advise (va_alist)
  845. va_dcl
  846. {
  847.     int     code;
  848.     va_list ap;
  849.  
  850.     va_start (ap);
  851.  
  852.     code = va_arg (ap, int);
  853.  
  854.     _ll_log (pp_log_norm, code, ap);
  855.  
  856.     va_end (ap);
  857. }
  858. #else
  859. /* VARARGS3 */
  860.  
  861. void    advise (code, what, fmt)
  862. char   *what,
  863.        *fmt;
  864. int     code;
  865. {
  866.     advise (code, what, fmt);
  867. }
  868. #endif
  869.